package in.muton.panels.paginator;

import in.muton.edushare.EduSharePage;
import in.muton.edushare.pages.EduShareBasePage;
import in.muton.edushare.pages.common.EdusharePanel;
import in.muton.edushare.pages.publicpages.DeptWideLink;
import in.muton.edushare.pages.publicpages.UserSquareLink;
import in.muton.panels.paginator.badgehelpers.course.BatchBadgeInterface;
import in.muton.panels.paginator.badgehelpers.course.CourseBadgeInterface;
import in.muton.panels.paginator.badgehelpers.course.DeptBadgeInterface;
import in.muton.panels.paginator.badgehelpers.course.ProgramBadgeInterface;
import in.muton.panels.paginator.badgehelpers.user.BadgeRoles;
import in.muton.panels.paginator.components.badges.BatchBadge;
import in.muton.panels.paginator.components.badges.CourseBadge;
import in.muton.panels.paginator.components.badges.CourseBadgeWide;
import in.muton.panels.paginator.components.badges.CurriculaBadge;
import in.muton.panels.paginator.components.badges.DeptBadge;
import in.muton.panels.paginator.components.badges.GroupBadge;
import in.muton.panels.paginator.components.badges.UnivBadge;
import in.muton.panels.paginator.components.badges.UserBadge;
import in.muton.panels.paginator.components.listitems.BatchListItem;
import in.muton.panels.paginator.components.listitems.CourseListItem;
import in.muton.panels.paginator.components.listitems.DeptListItem;
import in.muton.panels.paginator.components.listitems.GroupListItem;
import in.muton.panels.paginator.components.listitems.UserListItem;
import in.muton.panels.paginator.helpers.BadgeInterface;

import java.util.List;

import org.apache.wicket.Page;
import org.apache.wicket.markup.html.JavascriptPackageResource;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;

import com.edushare.common.vo.Batches;
import com.edushare.common.vo.CourseInstances;
import com.edushare.common.vo.Courses;
import com.edushare.common.vo.Curricula;
import com.edushare.common.vo.Departments;
import com.edushare.common.vo.Groups;
import com.edushare.common.vo.Universities;
import com.edushare.common.vo.Users;

public class EntityListing<T> extends EdusharePanel {
	private static final long serialVersionUID = -4404798526715049224L;

	public EntityListing(String id, IModel<List<IModel<T>>> listModel,
			BadgeInterface b, EduSharePage page) {
		super(id);
		this.listModel = listModel;
		this.bif = b;
		init();
	}

	public EntityListing(String id, IModel<List<IModel<T>>> listModel,
			int type, BadgeInterface b, EduShareBasePage page) {
		super(id, page);
		this.listModel = listModel;
		this.bif = b;
		init();
		setPage(page);
	}

	public EntityListing(String id, IModel<List<IModel<T>>> listModel,
			EduSharePage page) {
		this(id, listModel, null, page);
	}

	public void init() {
		add(JavascriptPackageResource.getHeaderContribution(
				BatchListItem.class, "ListItemFile.js"));
		Link<Void> l = new Link<Void>("swapMode") {
			private static final long serialVersionUID = 538517086756653979L;

			@Override
			public void onClick() {
				swapView();
			}

			@Override
			public boolean isVisible() {
				return listModel.getObject().size() > 0;
			}
		};
		add(l);
		l.add(new Label("currentMode", new Model<String>() {
			private static final long serialVersionUID = 1L;

			@Override
			public String getObject() {
				return getCurrentViewString();
			}
		}));

		pageableListView = new PageableListView<IModel<T>>("entityLV",
				listModel, 20) {
			private static final long serialVersionUID = -2465522736364821755L;

			@Override
			protected void populateItem(ListItem<IModel<T>> arg0) {
				EntityListing.this.populateItem(arg0);
			}
		};
		pageNavigator = new EdusharePageNavigator("navigator", pageableListView);
		add(pageableListView);
		add(pageNavigator);
	}

	private void populateItem(ListItem<IModel<T>> arg0) {
		if (getBasePage() == null) {
			Page p = this.getPage();
			if (p != null && p instanceof EduShareBasePage)
				setPage((EduShareBasePage) p);
		}

		if (getCurrentView() == LIST_VIEW)
			populateListView(arg0);
		else
			populateBadgeView(arg0);
	}

	@SuppressWarnings("unchecked")
	private void populateListView(ListItem<IModel<T>> arg0) {
		T object = arg0.getModelObject().getObject();
		if (object instanceof Departments) {
			arg0.add(new DeptListItem("entity", getBasePage(),
					(IModel<Departments>) arg0.getModelObject(),
					(DeptBadgeInterface) bif));
		} else if (object instanceof Courses) {
			arg0.add(new CourseListItem("entity", getBasePage(),
					(IModel<Courses>) (arg0.getModelObject()),
					(CourseBadgeInterface) bif, 0));
		} else if (object instanceof Users) {
			arg0.add(new UserListItem("entity", getBasePage(),
					(IModel<Users>) arg0.getModelObject(), (BadgeRoles) bif));
		} else if (object instanceof Universities) {
			arg0.add(new UnivBadge("entity", (IModel<Universities>) arg0
					.getModelObject()));
		} else if (object instanceof Curricula) {
			arg0.add(new CurriculaBadge("entity", getBasePage(),
					(IModel<Curricula>) arg0.getModelObject(),
					(ProgramBadgeInterface) bif));
		} else if (object instanceof Batches) {
			arg0.add(new BatchListItem("entity", getBasePage(),
					(IModel<Batches>) arg0.getModelObject(),
					(BatchBadgeInterface) bif));
		} else if (object instanceof CourseInstances) {
			arg0.add(new CourseListItem("entity", getBasePage(),
					(IModel<CourseInstances>) arg0.getModelObject(), null));
		} else if (object instanceof Groups) {
			arg0.add(new GroupListItem("entity", (IModel<Groups>) arg0
					.getModelObject(), getBasePage()));
		} else {
			arg0.add(new EmptyPanel("entity"));
		}
		arg0.setRenderBodyOnly(true);
		return;
	}

	@SuppressWarnings("unchecked")
	private void populateBadgeView(ListItem<IModel<T>> arg0) {
		T object = arg0.getModelObject().getObject();
		if (object instanceof Departments) {
			switch (type) {
			case DEFAULT:
				arg0.add(new DeptBadge("entity", getBasePage(),
						(IModel<Departments>) arg0.getModelObject(),
						(DeptBadgeInterface) bif));
				break;
			case WIDE:
				arg0.add(new DeptWideLink("entity", (IModel<Departments>) arg0
						.getModelObject()));
				break;
			}
		} else if (object instanceof Courses) {
			switch (type) {
			case (DEFAULT):
				arg0.add(new CourseBadge("entity", getBasePage(),
						(IModel<Courses>) (arg0.getModelObject()),
						(CourseBadgeInterface) bif));
				break;
			case (WIDE):
				arg0.add(new CourseBadgeWide("entity", (IModel<Courses>) (arg0
						.getModelObject())));
				break;
			}
		} else if (object instanceof Users) {
			switch (type) {
			case DEFAULT:
				arg0
						.add(new UserBadge("entity", getBasePage(),
								(IModel<Users>) arg0.getModelObject(),
								(BadgeRoles) bif));
				break;
			case SQUARE:
				arg0.add(new UserSquareLink("entity", (IModel<Users>) arg0
						.getModelObject()));
				break;
			}
		} else if (object instanceof Groups) {
			arg0.add(new GroupBadge("entity", (IModel<Groups>) arg0
					.getModelObject(), getBasePage()));
		} else if (object instanceof Universities) {
			arg0.add(new UnivBadge("entity", (IModel<Universities>) arg0
					.getModelObject()));
		} else if (object instanceof Curricula) {
			arg0.add(new CurriculaBadge("entity", getBasePage(),
					(IModel<Curricula>) arg0.getModelObject(),
					(ProgramBadgeInterface) bif));
		} else if (object instanceof Batches) {
			arg0.add(new BatchBadge("entity", getBasePage(),
					(IModel<Batches>) arg0.getModelObject(),
					(BatchBadgeInterface) bif));
		} else if (object instanceof CourseInstances) {
			arg0.add(new CourseBadge("entity", getBasePage(),
					(IModel<CourseInstances>) arg0.getModelObject()));
		} else {
			arg0.add(new EmptyPanel("entity"));
		}
		arg0.setRenderBodyOnly(true);
		return;
	}

	public String getCurrentViewString() {
		if (currentView == LIST_VIEW)
			return BADGE_VIEW_STRING;
		return LIST_VIEW_STRING;
	}

	public void swapView() {
		if (currentView == BADGE_VIEW) {
			this.currentView = LIST_VIEW;
			this.pageableListView.setRowsPerPage(50);
		} else {
			this.currentView = BADGE_VIEW;
			this.pageableListView.setRowsPerPage(20);
		}
	}

	public int getCurrentView() {
		return currentView;
	}

	PageableListView<IModel<T>> pageableListView = null;
	IModel<List<IModel<T>>> listModel = null;
	private int currentView = BADGE_VIEW;
	EdusharePageNavigator pageNavigator = null;
	private int type = DEFAULT;
	private BadgeInterface bif = null;

	public static final int DEFAULT = 0;
	public static final int WIDE = 1;
	public static final int SQUARE = 2;
	public static final String LIST_VIEW_STRING = "List View";
	public static final String BADGE_VIEW_STRING = "Badge View";
	public static final int LIST_VIEW = 0;
	public static final int BADGE_VIEW = 1;
}
